<?php

namespace app\award;

use app\controllers\h5\uni\HomeController;
use app\models\AdminSupplier;
use app\models\AwardList;
use app\models\AwardResult;
use app\models\order\Order;
use app\models\order\OrderItem;
use app\models\product\Product;
use app\models\product\ProductAreaList;
use app\models\Queue;
use app\models\SetProductCommission;
use app\models\SetUserUp;
use app\models\user\User;
use app\models\user\UserAccount;
use app\models\user\UserAddress;
use app\models\user\UserCommission;
use app\models\user\UserLevel;
use app\models\user\UserScoreTicket;
use app\models\UserBalance;
use app\models\UserStore;
use app\models\UserStoreLog;
use app\services\Chain;
use yii\helpers\ArrayHelper;

class Award
{
    protected $user;
    protected $order;
    protected $set;

    protected $items;

    // 总金额
    protected $amount;

    // 复购商品单价
    protected $price;

    // 复购数量
    protected $box;

    protected $is_bao = false;
    protected $is_merchant = false;
    protected $is_wy = false;
    protected $is_td = false;

    // 是否为重算订单
    protected $is_reset = false;


    public function __construct(Order $order, $is_reset = false)
    {
        $this->order = $order;
        $this->user = User::findOne(['id' => $order->user_id]);
        $this->set = SetUserUp::getLastOne();

        $this->is_reset = $is_reset;

        $this->items = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->all();

        $first_order_item = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->orderBy(['id' => SORT_ASC])
            ->limit(1)
            ->one();
        $product_id = $first_order_item->product_id;

        // 复购商品价格
        $this->price = Product::find()
            ->select(['price'])
            ->where(['id' => $product_id])
            ->scalar();

        $this->amount = $this->order->total_pay - $this->order->total_freight;

        // 线下扫码, 也返
        if ($this->order->pay_type == 121) {
            $this->bao();
            $this->score();
        } else {
            // 爆品
            $this->is_bao = ProductAreaList::checkInArea($product_id, Product::$areaMap['REPORT']);
            if ($this->is_bao) {
                $this->bao();
                $this->score();
            }

            // 线下商家
            $this->is_merchant = ProductAreaList::checkInArea($product_id, Product::$areaMap['MERCHANT']);
            if ($this->is_merchant) {
                $this->bao();
                $this->score();
            }

            // 文娱区
            $this->is_wy = ProductAreaList::checkInArea($product_id, Product::$areaMap['WY']);
            if ($this->is_wy) {
                $this->bao();
                $this->score();
            }

            // 特定区
            $this->is_td = ProductAreaList::checkInArea($product_id, Product::$areaMap['TD']);
            if ($this->is_td) {
                $this->bao();
                $this->score();
                $this->td();
            }
        }




        // 生成抽奖码
        if (!$is_reset) {
            $this->createAwardSn();
        }

        // 抽奖
        if (!$is_reset) {
            $this->award();
        }
    }

    private function createAwardSn()
    {
        $set = SetUserUp::getLastOne()->award_amount;

        if ($this->order->total_pay >= $set) {
            $this->order->award_sn = $this->order->sn . mt_rand(1111, 9999);
            $this->order->award_status = 1;
            $this->order->save();
        }
    }

    private function award()
    {
        $count = HomeController::awardOrderCount();
        $need = (int)SetUserUp::getLastOne()->award_num;

        // 开始抽奖
        if ($count % $need == 0) {

            // 待抽奖号码
            $ids = Order::find()
                ->where(['award_status' => 1])
                ->select(['award_sn'])
                ->column();
            shuffle($ids);

            // 抽奖规则
            $list = AwardList::find()
                ->where(['status' => 1])
                ->all();
            if ($list) {
                foreach ($list as $item) {
                    // var_dump($ids);
                    if ($item['count'] >= 1) {
                        $ids = $this->saveAward($ids, $item);
                        // var_dump($ids);exit;
                    }
                }
            }

            // 测试, n = 1, 有特殊
            // $x = ['a', 'b', 'c', 'd', 'f'];
            // var_dump($this->_rand($x, 0));exit;

            // exit;
        }

    }

    // 保存中奖
    private function saveAward($arr, AwardList $item)
    {
        // 抽出中奖人
        $list = $this->_rand($arr, $item['count']);

        // 中奖人
        if (count($list) > 1) {
            $inAward = $list[1];
            // var_dump($list);
            for ($i = 0; $i < count($inAward); $i++) {
                // var_dump($inAward[$i]);

                $order = Order::findOne(['award_sn' => $inAward[$i]]);

                $model = new AwardResult();
                $model->user_id = $order->user_id;
                $model->balance = $item['balance'];
                $model->score = $item['score'];
                $model->award_id = $item['id'];
                $model->award_sn = $order->award_sn;
                $model->status = 1;
                $model->log = json_encode($item);
                $model->save();

                $order->award_status = 2;
                $order->save();

                // 保存到佣金, 233是为了其它地方不被删除
                $commission = new UserCommission();
                $commission->user_id = $model->user_id;
                $commission->score = $model->score;
                $commission->balance = $model->balance;
                $commission->status = 1;
                $commission->award_type = '233';
                $commission->award_name = '中奖';
                $commission->save();

                $account = UserAccount::findOne(['user_id' => $model->user_id]);
                if ($account) {
                    $account->balance += $model->balance;
                    $account->score += $model->score;
                    $account->save();
                }


            }
        }

        // exit;

        return count($list) > 0 ? $list[0]: [];
    }

    // 从数组中随机获取元素
    private function _rand($arr, $n)
    {
        if ($arr) {
            if ($n > count($arr)) {
                $n = count($arr);
            }
            if ($n < 1) {
                $n = 1;
            }
            $keys = array_rand($arr, $n);
            if ($n == 1) {
                shuffle($arr);
                $x = array_pop($arr);
                return [
                    $arr,
                    [$x]
                ];
            }
            $list = [];
            foreach ($keys as $v) {
                array_push($list, $arr[$v]);
                unset($arr[$v]);
            }
            return [
                $arr,
                $list
            ];
        }

        return [[],[]];
    }

    // 送联娱券
    private function score()
    {
        // 使用了联娱券, 则不返了
        if ($this->order->use_score > 0 || $this->order->use_ticket > 0) {
            return;
        }


        $ratio = SetUserUp::getLastOne()->ratio_score;

        $amount = $this->order->total_pay - $this->order->total_freight;
            // - ($this->order->use_score / $ratio) - $this->order->use_ticket;

        // 如果是供应商(线下商家)产品, 减掉成本
        // 平台产品, 默认扣80%
        $s_sum = 80;
        if ($this->order->supplier_id > 0) {
            $r = AdminSupplier::findOne(['id' => $this->order->supplier_id]);
            if ($r->discount > 0) {
                $s_sum = (100 - $r->discount);
            }
            // 如果是商家产品, 并且有 中介 把中介的扣掉
            if ($r->vip6_id > 0) {
                $x = UserLevel::find()
                    ->where(['value' => UserLevel::$keys['vip6']])
                    ->select(['ratio'])
                    ->scalar();
                $s_sum += $x;
            }
        }

        // 减掉 佣金
        $c_sum = (float)UserLevel::find()
            ->where(['hide' => 0])
            ->andWhere(['>', 'ratio', 0])
            ->sum('ratio');
        // 改成10个点
        $c_sum = 10;

        $total = $amount * (100 - $c_sum - $s_sum) / 100 * $ratio;

        // 保存记录
        if ($total >= 0.01) {
            $model = new UserCommission();
            $model->user_id = $this->user->id;
            $model->fans_id = 0;
            $model->order_id = $this->order->id;
            $model->score = $total;
            $model->status = 1;
            $model->award_name = '下单送券';
            $model->award_type = 2;
            $model->save();
            $account = UserAccount::findOne(['user_id' => $this->user->id]);

            if ($account) {
                $account->score += $total;
                $account->save();
            }
        }
    }

    // 送定向券
    private function td()
    {
        $sum = 0;
        foreach ($this->items as $item) {
            $p = SetProductCommission::find()
                ->where(['product_id' => $item['product_id']])
                ->one();
            if ($p) {
                $sum += $item['quantity'] * $p->ticket;
            }
        }

        // var_dump($sum);exit;

        // 保存记录
        if ($sum > 0.01) {
            $model = new UserCommission();
            $model->user_id = $this->user->id;
            $model->fans_id = 0;
            $model->order_id = $this->order->id;
            $model->ticket = $sum;
            $model->status = 1;
            $model->award_name = '下单送券';
            $model->award_type = 3;
            $model->save();
            $account = UserAccount::findOne(['user_id' => $this->user->id]);

            if ($account) {
                $account->ticket += $sum;
                $account->save();
            }
        }
    }

    private function bao()
    {

        // 使用了联娱券, 则不返了
        if ($this->order->use_score > 0 || $this->order->use_ticket > 0) {
            return;
        }

        $ratio = SetUserUp::getLastOne()->ratio_score;

        // todo 这里可能会出现负, 因为运费也可能是联娱券支付的,
        $amount = $this->order->total_pay - $this->order->total_freight;
            // - ($this->order->use_score / $ratio) - $this->order->use_ticket;


        // 这里改成 业务员, 中介有
        // 根据商家绑定的对家来
        if ($this->order->supplier_id > 0) {
            $merchant = AdminSupplier::findOne(['id' => $this->order->supplier_id]);
            if ($merchant) {
                if ($merchant->vip1_id > 0) {
                    $commission = $amount * $this->_getRatio(UserLevel::$keys['vip1']);
                    $this->saveCommission($merchant->vip1_id, $commission, 11, '业务员收益', 1);
                }
                if ($merchant->vip6_id > 0) {
                    $commission = $amount * $this->_getRatio(UserLevel::$keys['vip6']);
                    $this->saveCommission($merchant->vip6_id, $commission, 12, '中介收益', 1);
                }
            }
        }
        return;

        // 如果是供应商产品, 则只用让利算
        // if ($this->order->supplier_id > 0) {
        //     $r = AdminSupplier::findOne(['id' => $this->order->supplier_id]);
        //     if ($r->discount > 0) {
        //         $amount = ($this->order->total_pay - $this->order->total_freight) * $r->discount / 100;
        //     }
        // }

        // var_dump($this->order->total_pay , $this->order->total_freight
        //     , ($this->order->use_score / $ratio) , $this->order->use_ticket, $amount);exit;


        // 后面加的一个"直推", 也是一个身份
        $r = Chain::getReferrer($this->order->user_id, true);
        if ($r && $r->level == UserLevel::$keys['svip']) {
            $commission = $amount * $this->_getRatio(UserLevel::$keys['svip']);
            $this->saveCommission($r->id, $commission, 1, '直推返佣');
        }


        $has_vip1 = false;
        $has_vip2 = false;
        $has_vip3 = false;
        $has_vip4 = false;
        $has_vip5 = false;

        $chain = Chain::getReferrerChain($this->user->id, [
            UserLevel::$keys['vip1'],
            UserLevel::$keys['vip2'],
            UserLevel::$keys['vip3'],
            UserLevel::$keys['vip4'],
            UserLevel::$keys['vip5'],
        ], true);

        foreach ($chain as $user) {
            if (!$has_vip1 && $user->level == UserLevel::$keys['vip1']) {
                $commission = $amount * $this->_getRatio(UserLevel::$keys['vip1']);
                $this->saveCommission($user->id, $commission, 1, '返佣');
                $has_vip1 = true;
            }
            if (!$has_vip2 && $user->level == UserLevel::$keys['vip2']) {
                $commission = $amount * $this->_getRatio(UserLevel::$keys['vip2']);
                $this->saveCommission($user->id, $commission, 1, '返佣');
                $has_vip2 = true;
            }
            if (!$has_vip3 && $user->level == UserLevel::$keys['vip3']) {
                // $commission = $amount * $this->_getRatio(UserLevel::$keys['vip3']);
                // $this->saveCommission($user->id, $commission, 1, '返佣');
                $has_vip3 = true;
            }
            if (!$has_vip4 && $user->level == UserLevel::$keys['vip4']) {
                // $commission = $amount * $this->_getRatio(UserLevel::$keys['vip4']);
                // $this->saveCommission($user->id, $commission, 1, '返佣');
                $has_vip4 = true;
            }
            if (!$has_vip5 && $user->level == UserLevel::$keys['vip5']) {
                $commission = $amount * $this->_getRatio(UserLevel::$keys['vip5']);
                $this->saveCommission($user->id, $commission, 1, '返佣');
                $has_vip5 = true;
                break;
            }
        }

        // 根据收货地址处理 县区 城市运营中心
        if ($this->order->pay_type != 121) {
            $address = UserAddress::findOne(['id' => $this->order->user_address]);
            $vip3 = User::findOne(['address_up' => $address->area_id]);
            $vip4 = User::findOne(['address_up2' => $address->city_id]);
            if ($vip3) {
                $commission = $amount * $this->_getRatio(UserLevel::$keys['vip3']);
                $this->saveCommission($vip3->id, $commission, 1, '返佣');
            }
            if ($vip4) {
                $commission = $amount * $this->_getRatio(UserLevel::$keys['vip4']);
                $this->saveCommission($vip4->id, $commission, 1, '返佣');
            }
        }

    }

    private function _getRatio($value)
    {
        return UserLevel::find()
            ->where(['value' => $value])
            ->select(['ratio'])
            ->scalar() / 100;
    }

    // 保存佣金 (await balance)
    protected function saveCommission($user_id, $balance, $type, $name, $status = 0)
    {
        if ($balance >= 0.01) {
            $model = new UserCommission();
            $model->user_id = $user_id;
            $model->fans_id = $this->order->user_id;
            $model->order_id = $this->order->id;
            $model->balance = $balance;
            $model->status = $status;
            $model->award_name = $name;
            $model->award_type = $type;
            $model->save();
            $account = UserAccount::findOne(['user_id' => $user_id]);

            if ($account) {
                if ($status == 1) {
                    $account->balance += $balance;
                } else {
                    $account->await_balance += $balance;
                }

              $account->save();
            }

            // balance logs
            if ($status == 1) {
                UserBalance::addLog($model->user_id,
                    $account->balance, $model->balance, $account->balance + $model->balance, '返佣', $this->order->id);
            }

            return true;
        }
    }

}